package com.bcx.wind.workflow.imp.cmd.managercmd;

import com.bcx.wind.workflow.access.QueryFilter;
import com.bcx.wind.workflow.core.constant.WorkflowOperate;
import com.bcx.wind.workflow.entity.WindActHistory;
import com.bcx.wind.workflow.entity.WindOrder;
import com.bcx.wind.workflow.entity.WindTask;
import com.bcx.wind.workflow.interceptor.Command;
import com.bcx.wind.workflow.interceptor.CommandContext;
import com.bcx.wind.workflow.pojo.WindUser;
import com.bcx.wind.workflow.support.Assert;
import com.bcx.wind.workflow.support.JsonHelper;
import com.bcx.wind.workflow.support.ObjectHelper;
import com.bcx.wind.workflow.support.TimeHelper;

import java.util.List;
import java.util.Map;

import static com.bcx.wind.workflow.core.constant.OrderVariableConstant.*;
import static com.bcx.wind.workflow.message.ErrorCode.*;

public class CloseTaskCommand implements Command<Integer> {

    /**
     * 任务ID
     */
    private String taskId;

    /**
     * 用户信息
     */
    public WindUser windUser;

    /**
     * 需要关闭的任务
     */
    private WindTask windTask ;


    /**
     * 关闭任务所属的流程实例
     */
    private WindOrder windOrder;
    /**
     * 执行数据
     */
    private CommandContext commandContext;

    public CloseTaskCommand(String taskId,WindUser windUser){
        this.taskId = taskId;
        this.windUser = windUser;
    }

    @Override
    public Integer executor(CommandContext context) {
        try{
            this.commandContext = context;
            return execute();
        }catch (Exception e) {
            context.log(e);
            return 0;
        }
    }

    private Integer execute() {
        //校验是否可以关闭
        checkTaskId();
        //更新流程实例变量中的变量数据
        changeWindOrderVariable();
        //执行关闭
        closeOperate();
        return 1;
    }

    private void closeOperate() {
        //更新流程实例
        this.commandContext.access().updateOrderInstance(this.windOrder);
        //删除任务以及审批人
        this.commandContext.access().removeTaskActorByTaskId(this.taskId);
        this.commandContext.access().removeTaskInstanceById(this.taskId);
        //更新履历
        QueryFilter filter = new QueryFilter()
                .setTaskId(this.taskId);
        List<WindActHistory> windActHistorys = this.commandContext.access().selectActiveHistoryList(filter);
        for(WindActHistory history : windActHistorys){
            history.setSubmitUserVariable(JsonHelper.toJson(user()))
                    .setOperate(WorkflowOperate.close.name())
                    .setSuggest(user().getUserId()+" close task "+windTask.getId()+" success ")
                    .setApproveTime(TimeHelper.nowDate())
                    .setActorId(user().getUserId())
                    .setActorName(user().getUserName());
            this.commandContext.access().updateActiveHistory(history);
        }
    }

    private void changeWindOrderVariable() {

        Map<String,Object> variable = this.windOrder.variable();
        Object jointlyMinCount = variable.get(JOINTLY_MIN_COUNT);
        if(!ObjectHelper.isEmpty(jointlyMinCount)){
            Map<String,Object> map = JsonHelper.objectToMap(jointlyMinCount);

            if(!ObjectHelper.isEmpty(map)){
                Object approveUserCount = map.get(this.windTask.getTaskName());

                if (!ObjectHelper.isEmpty(approveUserCount)) {
                    Map<String,Object> approveUserCountMap = JsonHelper.objectToMap(approveUserCount);

                    if(!ObjectHelper.isEmpty(approveUserCountMap)){
                        Object successCount = approveUserCountMap.get(JOINTLY_SUCCESS_COUNT);
                        Object nowCount = approveUserCountMap.get(JOINTLY_NOW_COUNT);
                        if(!ObjectHelper.hasEmpty(successCount,nowCount)){
                            int success = Integer.parseInt(successCount.toString());
                            int now = Integer.parseInt(nowCount.toString());
                            //校验是否可以关闭
                            Assert.isTrueError(TASK_IS_ONLY,success - now <=1);
                            approveUserCountMap.put(JOINTLY_SUCCESS_COUNT,Integer.toString(success - 1));
                            map.put(this.windTask.getTaskName(),approveUserCountMap);
                            variable.put(JOINTLY_MIN_COUNT,map);
                            this.windOrder.setVariable(JsonHelper.toJson(variable));
                        }
                    }
                }

            }
        }

    }


    /**
     * 校验任务是否合法，是否可以关闭
     */
    private void checkTaskId(){
        Assert.notEmptyError(TASK_ID_IS_NULL,this.taskId);

        this.windTask = this.commandContext.access().getTaskInstanceById(this.taskId);
        Assert.notEmptyError(TASK_ID_IS_NULL,windTask);

        this.windOrder = this.commandContext.access().getOrderInstanceById(this.windTask.getOrderId());
        Assert.notEmptyError(DATABASE_OPERATE_ERROR,this.windOrder);

        QueryFilter filter = new QueryFilter()
                .setOrderId(this.windOrder.getId());
        List<WindTask> windTasks = this.commandContext.access().selectTaskInstanceList(filter);
        Assert.isTrueError(TASK_IS_ONLY,windTasks.size() == 1);
    }



    private WindUser user(){
        return this.windUser == null ? new WindUser()
                .setUserId("admin")
                .setUserName("管理员") : this.windUser;
    }

}
